// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.2 OR LicenseRef-Slint-commercial

// cSpell: ignore Heade

import { Button, ComboBox, ListView, ScrollView, VerticalBox } from "std-widgets.slint";
import { ComponentList, ComponentListItem } from "component-list.slint";
import { DrawArea, DrawAreaMode, DropMark, LayoutKind, Selection } from "draw-area.slint";
import { HeaderBar } from "header-bar.slint";
import { Diagnostics, DiagnosticsOverlay } from "diagnostics-overlay.slint";

export { Diagnostics, DropMark, LayoutKind }

export component PreviewUi inherits Window {
    in property <[ComponentListItem]> known-components;
    in property <[Diagnostics]> diagnostics;
    in property <[Selection]> selections;
    in-out property <DropMark> drop-mark;
    in property <[string]> known-styles;
    in property <bool> experimental: false;
    in property <bool> show-preview-ui: true;
    in property <component-factory> preview-area;
    in property <string> status-text;
    in-out property <string> current-style;
    out property <bool> design-mode;

    pure callback can-drop(/* component_type */ string, /* x */ length, /* y */ length, /* on-drop-area */ bool) -> bool;
    callback drop(/* component_type */ string, /* x */ length, /* y */ length);
    callback selected-element-update-geometry(/* x */ length, /* y */ length, /* width */ length, /* height */ length);
    callback selected-element-delete();
    callback select-at(/* x */ length, /* y */ length, /* enter_component? */ bool);
    callback select-behind(/* x */ length, /* y */ length, /* enter_component* */ bool, /* reverse */ bool);
    callback show-document(/* url */ string, /* line */ int, /* column */ int);
    callback style-changed();
    callback reselect();
    callback unselect();

    property <length> border: 20px;
    property <length> side-bar-width: 200px;

    title: "Slint Live-Preview";
    icon: @image-url("assets/slint-logo-small-light.png");

    VerticalLayout {
        if (!show-preview-ui): no-ui-drawing-rect := Rectangle {
            VerticalLayout {
                ComponentContainer {
                    component-factory <=> root.preview-area;
                }
            }

            // Diagnostics overlay:
            DiagnosticsOverlay {
                width: 100%;
                height: 100%;
                diagnostics <=> root.diagnostics;
                show-document(url, line, column) => {
                    root.show-document(url, line, column);
                }
            }
        }
        if (show-preview-ui): Rectangle {
            VerticalLayout {
                HeaderBar {
                    vertical-stretch: 0.0;

                    height: self.preferred-height;

                    pick-button := Button {
                        text: @tr("Design Mode");
                        checkable: true;
                        checked <=> root.design-mode;
                        clicked() => {
                            key-handler.focus();
                        }
                    }

                    Text {
                        text: @tr("Style:");
                        vertical-alignment: center;
                    }

                    style-select := ComboBox {
                        model: root.known-styles;
                        current-value <=> current-style;
                        selected(value) => {
                            root.style-changed();
                        }
                    }

                    Text {
                        text: root.status-text;
                        vertical-alignment: center;
                    }
                }

                HorizontalLayout {
                    left-sidebar := Rectangle {
                        VerticalBox {
                            ComponentList {
                                known-components <=> root.known-components;
                                preview-area-position-x: draw-area.preview-area-position-x;
                                preview-area-position-y: draw-area.preview-area-position-y;
                                preview-area-width: draw-area.preview-area-width;
                                preview-area-height: draw-area.preview-area-height;

                                can-drop(c, x, y, oda) => {
                                    return root.can-drop(c, x, y, oda);
                                }
                                drop(c, x, y) => {
                                    root.drop(c, x, y);
                                }
                            }
                        }

                        states [
                        visible when !pick-button.checked: {
                                width: 0px;
                            }
                            hidden when pick-button.checked: {
                                width: root.side-bar-width;
                            }
                        ]
                    }

                    draw-area := DrawArea {
                        design-mode <=> root.design-mode;
                        diagnostics <=> root.diagnostics;
                        preview-area <=> root.preview-area;
                        selections <=> root.selections;
                        drop-mark <=> root.drop-mark;

                        select-at(x, y, enter_component) => {
                            root.select-at(x, y, enter_component);
                        }
                        selected-element-update-geometry(x, y, w, h) => {
                            root.selected-element-update-geometry(x, y, w, h);
                        }
                        selected-element-delete() => {
                            root.selected-element-delete();
                        }
                        select-behind(x, y, stay_in_file, reverse) => {
                            root.select-behind(x, y, stay_in_file, reverse);
                        }
                        show-document(url, line, column) => {
                            root.show-document(url, line, column);
                        }
                        unselect() => {
                            root.unselect();
                        }
                        reselect() => {
                            root.reselect();
                        }
                    }

                    preferred-width: draw-area.preferred-width + root.side-bar-width/* for left-side-bar */;
                }
            }

            key-handler := FocusScope {
                enabled: draw-area.mode == DrawAreaMode.designing;

                key-released(event) => {
                    if event.text == Key.Delete {
                        // This `if` should not be necessary, but without it
                        // we do trigger deletion of Elements while errors
                        // are on screen.
                        if draw-area.mode == DrawAreaMode.designing {
                            root.selected-element-delete();
                        }
                        return accept;
                    }
                    reject
                }
            }
        }
    }
}
